#include "gpio.h"
#include "esm6800_drivers.h"
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

using namespace std;

pthread_mutex_t CGpio::mutex; 
CGpio* CGpio::pInstance = NULL; 

CGpio::CGpio()
{
    fd = open("/dev/em_gpio", O_RDWR);
    if(fd!=-1)
    {
        cout<<"open gpio dev success"<<endl;
    }
    else
    {
        cout<<"open gpio dev failed"<<endl;
    }
    
}

CGpio::~CGpio()
{
    if(fd!=-1)
    {
      close(fd);
      fd = -1;
      cout<<"gpio dev closed"<<endl;
    }
}

CGpio* CGpio::getInstance() 
{ 
   if (NULL == pInstance) 
   { 
     pthread_mutex_lock(&mutex); 
     if (NULL == pInstance) 
       pInstance = new CGpio(); 
     pthread_mutex_unlock(&mutex); 
   } 
//   else 
//   {
//       if(fd==-1)
//       {
//           fd = ("/dev/esm6800_gpio", O_RDWR);
//           if(fd!=-1)
//           {
//               cout<<"open gpio dev success"<<endl;
//           }
//       }
//   }
   return pInstance; 
}

void CGpio::openDev(void)
{
    if(fd==-1)
    {
       fd = ("/dev/esm6800_gpio", O_RDWR);
       if(fd!=-1)
       {
           cout<<"open gpio dev success"<<endl;
       }
    }
}

void CGpio::closeDev(void)
{
    if(fd!=-1)
    {
       close(fd);
       fd = -1;
       cout<<"gpio dev closed"<<endl;
    }
}

int CGpio::GPIO_OutEnable(unsigned int dwEnBits)
{
    int rc;
    struct double_pars	dpars;
    if(this->fd == -1)
    {
       return -1;
    }

    dpars.par1 = ESM6800_GPIO_OUTPUT_ENABLE;
    dpars.par2 = dwEnBits;

    rc = write(fd, &dpars, sizeof(struct double_pars));
    return rc;
}

int CGpio::GPIO_OutDisable(unsigned int dwEnBits)
{
    int rc;
    struct double_pars	dpars;
    if(this->fd == -1)
    {
       return -1;
    }

    dpars.par1 = ESM6800_GPIO_OUTPUT_DISABLE;
    dpars.par2 = dwEnBits;

    rc = write(this->fd, &dpars, sizeof(struct double_pars));
    return rc;
}

int CGpio::GPIO_OutSet(unsigned int dwSetBits)
{
    int rc;
    struct double_pars	dpars;
    
    if(this->fd == -1)
    {
       return -1;
    }
    dpars.par1 = ESM6800_GPIO_OUTPUT_SET;	// 2
    dpars.par2 = dwSetBits;

    rc = write(this->fd, &dpars, sizeof(struct double_pars));
    return rc;
}

int CGpio::GPIO_OutClear(unsigned int dwClearBits)
{
    int rc;
    struct double_pars	dpars;

    if(this->fd == -1)
    {
       return -1;
    }
    dpars.par1 = ESM6800_GPIO_OUTPUT_CLEAR;	// 3
    dpars.par2 = dwClearBits;

    rc = write(this->fd, &dpars, sizeof(struct double_pars));
    return rc;
}

int CGpio::GPIO_PinState(unsigned int* pPinState)
{
    int 				rc;
    struct double_pars	dpars;

    dpars.par1 = ESM6800_GPIO_INPUT_STATE;	// 5
    dpars.par2 = *pPinState;

    rc = read(fd, &dpars, sizeof(struct double_pars));
    if(!rc)
    {
        *pPinState = dpars.par2;
    }
    return rc;
}

